package io.github.eric.urpc.core.config;

import io.github.eric.urpc.core.conn.ConnectionListener;
import io.github.eric.urpc.core.handler.ProtoDecoder;
import io.github.eric.urpc.core.handler.ProtoEncoder;
import io.github.eric.urpc.core.conn.ConnectionManager;
import io.github.eric.urpc.core.rpc.MessageRegistrar;
import io.netty.util.HashedWheelTimer;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;

/**
 * 内部使用的上下文类，继承自配置类便于内部通过上下文即可拿到全量的信息。
 * 如果某个属性不需要暴露给用户配置，但又需要在内部传递，可以放置在该类中
 */
public abstract class AbstractContext extends AbstractConfig implements EventExecutorState {
    private final ProtoEncoder messageEncoder;
    private final ProtoDecoder messageDecoder;
    private final MessageRegistrar messageRegistrar;
    private HashedWheelTimer hashedWheelTimer;
    private final ExecutorService rpcExecutor;
    private ConnectionManager connectionManager;
    private boolean shutdown;
    private Logger logger;

    public AbstractContext(String side, ExecutorService rpcExecutor) {
        super(side);
        messageRegistrar = new MessageRegistrar();
        messageEncoder = new ProtoEncoder(this);
        messageDecoder = new ProtoDecoder(this);
        this.rpcExecutor = rpcExecutor;
        connectionListeners = new ArrayList<>();
    }

    public ProtoEncoder getMessageEncoder() {
        return this.messageEncoder;
    }

    public ProtoDecoder getMessageDecoder() {
        return this.messageDecoder;
    }

    public MessageRegistrar getMessageRegistrar() {
        return this.messageRegistrar;
    }

    public HashedWheelTimer getHashedWheelTimer() {
        return hashedWheelTimer;
    }

    public void setHashedWheelTimer(HashedWheelTimer hashedWheelTimer) {
        this.hashedWheelTimer = hashedWheelTimer;
    }

    public ExecutorService getRpcExecutor() {
        return this.rpcExecutor;
    }

    public ConnectionManager getConnectionManager() {
        return connectionManager;
    }

    public void setConnectionManager(ConnectionManager connectionManager) {
        this.connectionManager = connectionManager;
        if (connectionManager instanceof ConnectionListener) {
            connectionListeners.add(0, (ConnectionListener) connectionManager);
        }
    }

    @Override
    public boolean isShuttingDown() {
        return shutdown;
    }

    @Override
    public void shutdown() {
        shutdown = true;
    }

    @Override
    public Logger getLogger() {
        return logger;
    }

    public void setLogger(Logger logger) {
        this.logger = logger;
    }

}
